<?php
// 应用公共文件
/**
 * 获取客户端ip
 * User:于小涛
 * Date:2020/2/16
 * Time:17:56
 */
function get_client_ip(){
    if (isset($_SERVER))
    {
        if (isset($_SERVER['HTTP_CDN_SRC_IP']) && !empty($_SERVER['HTTP_CDN_SRC_IP'])){
            $ip=$_SERVER['HTTP_CDN_SRC_IP'];
            $ip = trim($ip);
            if (check_ip_valid($ip)) return $ip;
        }
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
            $ips = $_SERVER['HTTP_X_FORWARDED_FOR'];
            $ips = urldecode($ips);
            $arr = explode(',', $ips);
            /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */
            foreach ($arr as $ip)
            {
                $ip = trim($ip);

                if ($ip != 'unknown' && !empty($ip))
                {
                    if (check_ip_valid($ip)) return $ip;
                }
            }
        }
        if (isset($_SERVER['HTTP_CLIENT_IP']) && !empty($_SERVER['HTTP_CLIENT_IP']))
        {
            $ip=$_SERVER['HTTP_CLIENT_IP'];
            $ip = trim($ip);
            if (check_ip_valid($ip)) return $ip;
        }
        if (isset($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['REMOTE_ADDR']))
        {
            $ip=$_SERVER['REMOTE_ADDR'];
            $ip = trim($ip);
            if (check_ip_valid($ip)) return $ip;
        }
    }
    else
    {
        if (getenv('HTTP_X_FORWARDED_FOR'))
        {
            $ips = getenv('HTTP_X_FORWARDED_FOR');
            $ips = urldecode($ips);
            $arr = explode(',', $ips);
            /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */
            foreach ($arr as $ip)
            {
                $ip = trim($ip);

                if ($ip != 'unknown' && !empty($ip))
                {
                    if (check_ip_valid($ip)) return $ip;
                }
            }
        }
        if (getenv('HTTP_CLIENT_IP'))
        {
            $ip = getenv('HTTP_CLIENT_IP');
            $ip = trim($ip);
            if (check_ip_valid($ip)) return $ip;
        }
        if (getenv('REMOTE_ADDR'))
        {
            $ip = getenv('REMOTE_ADDR');
            $ip = trim($ip);
            if (check_ip_valid($ip)) return $ip;
        }
    }
    return '0.0.0.0';
}

function check_ip_valid($ip){
    $bool = filter_var($ip,FILTER_VALIDATE_IP, FILTER_FLAG_IPV4|FILTER_FLAG_IPV6);
    if(!$bool)//ipv4 和ipv6都不是返回false
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

/**
 * 递归替换数组key
 * User:于小涛
 * Date:2020/2/16
 * Time:17:56
 * @param array $arr_data 需要被替换的数组
 * @param array $arr_replace_keys 需要替换的key
 * @param bool $bool_reserve_source_key 是否保留原始key，默认否
 */
function recursionReplaceArrayKey(&$arr_data=array(),$arr_replace_keys=array(),$bool_reserve_source_key=false){
    foreach($arr_data as $key=>&$val){
        if(is_array($val)){
            recursionReplaceArrayKey($val,$arr_replace_keys,$bool_reserve_source_key);
        }
        if(array_key_exists($key,$arr_replace_keys)){
            $arr_data[$arr_replace_keys[$key]]=$val;
            if(!$bool_reserve_source_key){
                unset($arr_data[$key]);
            }
        }
    }
}

/**
 * 生成唯一的guid值
 * User:于小涛
 * Date:2020/2/18
 * Time:18:16
 */
function getGuid(){
    return md5(uniqid());
}
/**
 * 将数组元素的指定key当做一维数组的key
 * User:于小涛
 * Date:2020/2/21
 * Time:16:23
 * @param $arr_data
 * @param $str_key
 * @return array
 */
function array_item_key_to_self_key($arr_data,$str_key)
{
    $arr_re=array();
    foreach($arr_data as $arr_item)
    {
        $arr_re[$arr_item[$str_key]] = $arr_item;
    }
    return $arr_re;
}

/**
 * 给二维数组的某一个字段根据一个对应关系统一增加字段说明
 * User:于小涛
 * Date:2020/2/26
 * Time:17:20
 * @param $arr_data
 * @param $str_key
 * @param $arr_source_data
 * @param string $str_after_str
 */
function array_field_key_add_name(&$arr_data,$str_key,$arr_source_data,$str_after_str='_name'){
    foreach ($arr_data as &$arr_item){
        if(array_key_exists($arr_item[$str_key],$arr_source_data)){
            $arr_item[$str_key.$str_after_str] = $arr_source_data[$arr_item[$str_key]];
        }else{
            $arr_item[$str_key.$str_after_str] = '';
        }
    }
}

function getQueueConfig($filename,$model=''){
    static $queueDataConfig = null;
    $id = md5($filename."|||".$model);
    if (isset($queueDataConfig[$id]))
    {
        return $queueDataConfig[$id];
    }
    $filepath = "";
    if (strlen($model) <1){
        $filepath = base_path().'/cds/config/'.$filename.'.php';
    }
    else
    {
        $filepath = base_path().'/cds/config/'.$model.'/'.$filename.'.php';
    }
    if (!file_exists($filepath))
    {
        $queueDataConfig[$id] = ['ret'=>1,'reason'=>'文件不存在：'.$filepath,'data'=>null];
        return  $queueDataConfig[$id];
    }
    $arr_data = include $filepath;
    $queueDataConfig[$id] = ['ret'=>0,'reason'=>'ok','data'=>$arr_data];
    return  $queueDataConfig[$id];
}

function sysReturnData($ret,$reason,$data=null,$ex_data=null){
    return ['ret'=>$ret,'reason'=>$reason,'data'=>$data,'ex_data'=>$ex_data];
}

function sysGuidRand( $something = "rand" )
{
    $result = dechex(  time() );
    list ( $usec, $sec ) = explode ( ' ', microtime () );
    $str_millisecond = intval( substr ( $usec, 2, 3 ) );
    $result = $result.dechex( $str_millisecond );
    $a = "";
    if( isset( $_ENV ["COMPUTERNAME"] ) )
        $a .= $_ENV ["COMPUTERNAME"];
    if( isset( $_SERVER ["SERVER_ADDR"] ) )
        $a .= $_SERVER ["SERVER_ADDR"];
    if( isset( $_SERVER ["REMOTE_ADDR"] ) )
        $a .= $_SERVER ["REMOTE_ADDR"];

    $a = $a.rand(0,10000);
    $a = $a.rand(0,10000);
    $a = $a.rand(0,10000);
    $a = $a.microtime ();

    $result = $result.md5( $a.$something );
    return substr( $result, 0, 32 );
}

function sysMakeConfigDir($file_path,$is_absolute_path=false){
    $file_path = str_replace(' ','',$file_path);
    $file_path = str_replace('\\','/',$file_path);
    $file_path = str_replace('//','/',$file_path);
    if(strlen($file_path) <1){
        return sysReturnData(1,"文件路径为空：{$file_path}");
    }
    $arr_pathinfo = pathinfo($file_path);
    $file_basename = isset($arr_pathinfo['basename']) ? $arr_pathinfo['basename'] : '';
    if(!isset($arr_pathinfo['dirname']) || strlen($arr_pathinfo['dirname']) <1)
    {
        return sysReturnData(0,"文件路径为空：{$file_path}");
    }
    if (!$is_absolute_path){
        $base_file_dir = base_path()."/".$arr_pathinfo['dirname'];
        $base_file_dir = str_replace('//','/',$base_file_dir);
    }else{
        $base_file_dir = $arr_pathinfo['dirname'];
    }
    if (is_dir($base_file_dir))
    {
        return sysReturnData(0,"ok",array('base_dir'=>$file_path,'absolute_path'=>str_replace('//','/',$base_file_dir.'/'.$file_basename)));
    }
    $result=@mkdir($base_file_dir, 0777, true);
    if(!$result)
    {
        return sysReturnData(1,"创建文件夹失败：{$base_file_dir}",array('base_dir'=>$file_path,'absolute_path'=>str_replace('//','/',$base_file_dir.'/'.$file_basename)));
    }
    return sysReturnData(0,"ok",array('base_dir'=>$file_path,'absolute_path'=>str_replace('//','/',$base_file_dir.'/'.$file_basename)));
}

function sysEncrypt($txt, $key = 'system_encrypt_key')
{
    return base64_encode(openssl_encrypt($txt, 'DES-ECB', $key, OPENSSL_RAW_DATA));
}

function sysDecrypt($txt, $key = 'system_encrypt_key')
{
    return openssl_decrypt(base64_decode($txt), 'DES-ECB', $key, OPENSSL_RAW_DATA);
}

function sysEncryptKey($txt, $encrypt_key)
{
    $encrypt_key = md5($encrypt_key);
    $ctr = 0;
    $tmp = '';
    for($i = 0; $i < strlen($txt); $i++)
    {
        $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
        $tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
    }
    return $tmp;
}


function sysWriteFile($content,$file_path,$is_append=false,$is_absolute_path=false)
{
    if(strlen($content) < 1)
    {
        return sysReturnData(0,"内容为空不写入");
    }
    $file_path = str_replace(' ','',$file_path);
    $file_path = str_replace('\\','/',$file_path);
    $file_path = str_replace('//','/',$file_path);
    if(strlen($file_path) <1)
    {
        return sysReturnData(1,"文件路径为空：{$file_path}");
    }
    if (!$is_absolute_path){
        $base_file_dir = base_path()."/".$file_path;
    }else{
        $base_file_dir = $file_path;
    }
    if ($is_append)
    {
        $content = $content."\r\n";
        $result = file_put_contents($base_file_dir, $content, LOCK_EX|FILE_APPEND);
    }
    else
    {
        $result = file_put_contents($base_file_dir, $content, LOCK_EX);
    }
    if($result === false)
    {
        return sysReturnData(1,"文件写入失败：{$file_path}");
    }
    return sysReturnData(0,"ok");
}


function isJson($string)
{
    if(!is_string($string))
    {
        return false;
    }
    $string = strlen($string) <1 ? '' : trim($string);
    if(strlen($string) <1)
    {
        return false;
    }
    json_decode($string);
    return (json_last_error() == JSON_ERROR_NONE);
}

function isXml($string)
{
    if(!is_string($string))
    {
        return false;
    }
    $string = strlen($string) < 1 ? '' : trim($string);
    if(strlen($string) <1)
    {
        return false;
    }
    $xml_parser = xml_parser_create();
    if (! xml_parse($xml_parser, $string, true))
    {
        xml_parser_free($xml_parser);
        return false;
    }
    return true;
}

function sysTrimXmlHeader($xml,$encode=null)
{
    if(strlen($xml) < 1)
    {
        return '';
    }
    if(strlen($encode) > 0 )
    {
        $xml = mb_convert_encoding($xml,'UTF-8', $encode);
    }
    $xml = preg_replace('/\<\?\s*xml\s+version\s*\=\s*(\"|\').*(\"|\')\s+encoding\s*\=\s*(\"|\')[a-z0-9-]+(\"|\')\s*\?\>/i', '', $xml);
    $xml = preg_replace('/\<\?\s*xml\s+encoding\s*\=\s*(\"|\')[a-z0-9-]+(\"|\')\s*\?\>/i', '', $xml);
    $xml = preg_replace('/\<\?\s*xml\s+version\s*\=\s*(\"|\').*(\"|\')\s*\?\>/i', '', $xml);
    //去除XML中的单引号
// 		$xml = str_replace(array("\'"), "’", $xml);
    return trim($xml);
}

function SysMakeConfigData($array,$num=1)
{
    $str="";
    if (!is_array($array) || empty($array))
    {
        return $str;
    }
    if($num <2 )
    {
        $str="<?php\r\nreturn [\r\n";
    }
    else
    {
        $str="[\r\n";
    }
    foreach ($array as $key=>$value)
    {
        for ($i=0;$i<$num;$i++)
        {
            $str.="    ";
        }
        if(is_array($value) && !empty($value))
        {
            $strtemp = SysMakeConfigData($value,$num+1);
            $str.="'{$key}'=>{$strtemp}";
        }
        else
        {
            $str.="'{$key}'=>'{$value}',\r\n";
        }
    }
    if($num >1 )
    {
        for ($i=0;$i<$num;$i++)
        {
            $str.="    ";
        }
        $str .= "],\r\n";
    }
    else
    {
        $str .= "];";
    }
    return $str;
}


function unsetArrayKey(&$arr_data,$str_keys){
    $arr_keys=explode(',',$str_keys);
    foreach($arr_data as $key1=>&$arr_item){
        if(is_array($arr_item)){
            foreach ($arr_item as $key2=>&$arr_item2){
                if(in_array($key2,$arr_keys)){
                    unset($arr_item[$key2]);
                }
            }
        }
    }
}

function remainArrayKey($srr_data,$str_keys){
    $arr_keys=explode(',',$str_keys);
    $arr_re=[];
    foreach($srr_data as $key=>$arr_item){
        if(!array_key_exists($key,$arr_re)){
            $arr_re[$key] = [];
        }
        foreach($arr_item as $key2=>$mix_data){
            if(in_array($key2,$arr_keys)){
                $arr_re[$key][$key2]=$mix_data;
            }
        }
    }
    return $arr_re;
}


function readExcelData($str_excel_file_name,$bool_is_mutl_sheet=false){
    include_once dirname(__FILE__).'/lib/PHPExcel-1.8/Classes/PHPExcel/IOFactory.php';
    try {
        $inputFileType = PHPExcel_IOFactory::identify($str_excel_file_name);
        $objReader = PHPExcel_IOFactory::createReader($inputFileType);
        $objPHPExcel = $objReader->load($str_excel_file_name);
    } catch(Exception $e) {
        return array(
            'ret'=>1,
            'reason'=>$e->getMessage(),
        );
    }
    if($bool_is_mutl_sheet){
        $arr_excel_data=array();
        $int_sheet_count=$objPHPExcel->getSheetCount();
        for($i=0;$i<$int_sheet_count;$i++){
            $arr_sheet_data=array();
            $sheet = $objPHPExcel->getSheet($i);
            $highestRow = $sheet->getHighestRow();
            $highestColumn = $sheet->getHighestColumn();
            // 获取一行的数据
            for ($row = 1; $row <= $highestRow; $row++) {
                // Read a row of data into an array
                $arr_sheet_data[] = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, '', TRUE, FALSE);
            }
            $arr_excel_data[]=$arr_sheet_data;
        }

    }else{
        $sheet = $objPHPExcel->getSheet(0);
        $highestRow = $sheet->getHighestRow();
        $highestColumn = $sheet->getHighestColumn();
        // 获取一行的数据
        for ($row = 1; $row <= $highestRow; $row++) {
            // Read a row of data into an array
            $arr_excel_data[] = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, '', false, FALSE);
        }
    }
    $arr_re=array(
        'ret'=>0,
        'reason'=>'success',
        'data'=>$arr_excel_data,
    );
    return $arr_re;
}

/**
 * 数据导出
 * @param array $title 标题行名称
 * @param array $data 导出数据
 * @param string $fileName 文件名
 * @param string $savePath 保存路径
 * @param bool $isDown 是否下载  false--保存   true--下载
 * @return string  返回文件全路径
 * @throws PHPExcel_Exception
 * @throws PHPExcel_Reader_Exception
 * @throws PHPExcel_Writer_Exception
 */
function exportExcel($title=array(), $data=array(), $fileName='', $savePath='./', $isDown=false){
    include_once dirname(__FILE__).'/lib/PHPExcel-1.8/Classes/PHPExcel.php';
    $obj = new PHPExcel();
    //横向单元格标识
    $cellName = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ');
    $obj->getActiveSheet(0)->setTitle('sheet名称');   //设置sheet名称
    $_row = 1;   //设置纵向单元格标识
    if($title){
        $_cnt = count($title);
//        $obj->getActiveSheet(0)->mergeCells('A'.$_row.':'.$cellName[$_cnt-1].$_row);   //合并单元格
//        $obj->setActiveSheetIndex(0)->setCellValue('A'.$_row, '数据导出：'.date('Y-m-d H:i:s'));  //设置合并后的单元格内容
//        $_row++;
        $i = 0;
        foreach($title AS $v){   //设置列标题
            $obj->setActiveSheetIndex(0)->setCellValue($cellName[$i].$_row, $v);
            $i++;
        }
        $_row++;
    }
    //填写数据
    if($data){
        $i = 0;
        foreach($data AS $_v){
            $j = 0;
            foreach($_v AS $_cell){
                $obj->getActiveSheet(0)->setCellValue($cellName[$j] . ($i+$_row), $_cell);
                $j++;
            }
            $i++;
        }
    }
    //文件名处理
    if(!$fileName){
        $fileName = uniqid(time(),true);
    }
    $objWrite = PHPExcel_IOFactory::createWriter($obj, 'Excel2007');
    if($isDown){   //网页下载
        header('pragma:public');
        header("Content-Disposition:attachment;filename=$fileName.xlsx");
        $objWrite->save('php://output');exit;
    }
    $_fileName = iconv("utf-8", "gb2312", $fileName);   //转码
    $_savePath = $savePath.$_fileName.'.xlsx';
    $objWrite->save($_savePath);
    return $savePath.$fileName.'.xlsx';
}
/**
 * curl中的get请求
 * @param string $str_api 请求地址
 * @param array $arr_request_params 请求参数
 * @param array $arr_http_header http请求头信息
 * @param int $int_timeout 超时时间，单位：秒，默认5秒
 * @return array
 */
function curl_get($str_api,$arr_request_params=array(),$arr_http_header=array(),$int_timeout=5,$arr_options=array()){
    $obj_ch = curl_init();
    //如果参数不为空
    if(!empty($arr_request_params)){
        //将get参数拼接在api后面
        $str_params=http_build_query($arr_request_params);
        $str_api=trim($str_api,'?');
        $str_api=strpos($str_api,'?')===false?$str_api.'?'.$str_params:$str_api.'&'.$str_params;
    }
    curl_setopt($obj_ch,CURLOPT_URL,$str_api);
    //如果需要设置头信息
    if(!empty($arr_http_header)){
        curl_setopt($obj_ch,CURLOPT_HTTPHEADER,$arr_http_header);
    }
    foreach($arr_options as $arr_item){
        curl_setopt($obj_ch,$arr_item['key'],$arr_item['val']);
    }
    //设置超时时间
    curl_setopt($obj_ch,CURLOPT_TIMEOUT,$int_timeout);
    curl_setopt($obj_ch,CURLOPT_RETURNTRANSFER,true);
//        curl_setopt($obj_ch,CURLOPT_RETURNTRANSFER,1);
    //执行curl请求
    $mixed_data  = curl_exec($obj_ch);
    $int_error_no = curl_errno($obj_ch);
    $str_reason='success';
    if($int_error_no){
        $str_reason = curl_error($obj_ch);
    }
    curl_close($obj_ch);
    return array(
        'ret'=>$int_error_no,
        'reason'=>$str_reason,
        'data'=>$mixed_data,
    );
}

/**
 * curl中的post请求
 * @param string $str_api
 * @param array $arr_request_params,post请求的参数：key=>val格式
 * @param array $arr_http_header
 * @param int $int_timeout
 * @param array $arr_options
 * @return array
 */
function curl_post($str_api,$arr_request_params,$arr_http_header=array(),$int_timeout=5,$arr_options=array()){
    $obj_ch = curl_init();
    curl_setopt($obj_ch,CURLOPT_URL,$str_api);
    //如果需要设置头信息
    if(!empty($arr_http_header)){
        curl_setopt($obj_ch,CURLOPT_HTTPHEADER,$arr_http_header);
    }
    foreach($arr_options as $arr_item){
        curl_setopt($obj_ch,$arr_item['key'],$arr_item['val']);
    }
    //设置超时时间
    curl_setopt($obj_ch,CURLOPT_TIMEOUT,$int_timeout);
    //设置获取的信息以文件流的形式返回，而不是直接输出
    curl_setopt($obj_ch,CURLOPT_RETURNTRANSFER,true);
    //设置post方式提交
    curl_setopt($obj_ch, CURLOPT_POST, 1);
    //设置参数

    curl_setopt($obj_ch, CURLOPT_POSTFIELDS, $arr_request_params);
//        curl_setopt($obj_ch,CURLOPT_RETURNTRANSFER,1);
    //执行curl请求
    $mixed_data  = curl_exec($obj_ch);
    $int_error_no = curl_errno($obj_ch);
    $str_reason='success';
    if($int_error_no){
        $str_reason = curl_error($obj_ch);
    }
    curl_close($obj_ch);
    return array(
        'ret'=>$int_error_no,
        'reason'=>$str_reason,
        'data'=>$mixed_data,
    );
}